-- PRAGMA standard control signal mapping:
-- clk								=> clk
-- clk_48k							=> clk_48k
-- reset								=> reset
-- PAY ATTENTION:					RESET IS ACTIVE LOW
-- control_in	(0) 				=> volumizer_enable
--					(7)			 	=> multiply
--					(6)			 	=> divide
--					(5 downto 3) 	=> multiplicand
--					(2 downto 1)	=> UNUSED
--
--	control_out	(0)				<= enable
--					(3 downto 1)	<= multiplicand
-- 
-- PCM_data_in_right				=> PCM_data_in_right
-- PCM_data_in_left				=> PCM_data_in_left
-- PCM_data_out_right			<= PCM_data_out_right
-- PCM_data_out_left				<= PCM_data_out_left

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity PRM_time_1 is
  port(
    clk				: in std_logic;
	 clk_48k			: in std_logic;
    reset			: in std_logic;
	 
	 control_in		: in std_logic_vector(7 downto 0);
	 control_out	: out std_logic_vector(3 downto 0);
	 
    PCM_data_in_right	: in std_logic_vector(15 downto 0);
	 PCM_data_in_left		: in std_logic_vector(15 downto 0);
    PCM_data_out_right	: out std_logic_vector(15 downto 0);
	 PCM_data_out_left	: out std_logic_vector(15 downto 0)
    );
end entity PRM_time_1;

architecture Behavioral of PRM_time_1 is

	signal enable			: std_logic;
	signal multiplicand	: std_logic_vector(3 downto 0);
	signal multiply		: std_logic;
	signal divide			: std_logic;
	signal extended		: std_logic_vector(19 downto 0);
begin
	enable 			<= control_in(0);
	multiplicand	<= '0' & control_in(5 downto 3);	--force unsigned
	multiply			<= control_in(7);
	divide 			<= control_in(6);
	
	control_out		<= multiplicand(2 downto 0) & enable;
	
	PCM_data_out_left <= extended(15 downto 0);
	
	p_left: process(clk_48k, reset)
	begin
		if reset = '0' then
			extended <= (others => '0');
			PCM_data_out_right <= (others => '0');
		elsif clk_48k'event and clk_48k = '0' then
			if enable = '1' then
				if multiply = '1' then
					if divide = '1' then
						extended <= (others => '0');
					else
						extended <= PCM_data_in_left * multiplicand;
					end if;
				else
					if divide = '1' then
						extended <= sxt(PCM_data_in_left(15 downto 3) * multiplicand, 20);	--right shift by 3, multiply and sign extend
					else
						extended <= sxt(PCM_data_in_left, 20);											--sign extend
					end if;
				end if;
			else
				extended <= sxt(PCM_data_in_left, 20);													--sign extend
			end if;
		end if;
	end process;
	
end Behavioral;

